from queue import Queue
import serial
import serial.tools.list_ports
import threading
import time
import socket 
from log import logger

# 接收线程对象
class ComPortRead(threading.Thread):

    def __init__(self, queueRecv:Queue, recvFun, tag):
        super().__init__()
        self.daemon = True
        self.queueRecv = queueRecv
        self.hasGotExitSignal = False
        self.hasExit = False
        self.recvFun = recvFun
        self.tag = tag

    def exit(self):
        self.hasGotExitSignal = True
        
    def isAlive(self):
        return self.hasExit == False

    def run(self):
        logger.info("[ComPort] %s recv thread start" % self.tag)
        recvBytes = []
        while(True):
            self.buffer = bytearray()

            # 循环接收完整数据包
            while(True):
                try:
                    recvBytes = self.recvFun(1024)
                except:
                    self.hasGotExitSignal = True
                time.sleep(0.1)
                self.buffer += recvBytes
                if len(recvBytes) == 0:
                    break

            if self.hasGotExitSignal:
                break
            if len(self.buffer) != 0 and self.queueRecv is not None:
                self.queueRecv.put(list(self.buffer))
        
        self.hasExit = True
        logger.info("[ComPort] %s recv thread exit" % self.tag)

# 通讯接口父对象
class ComInterface:
    def __init__(self, name) -> None:
        self.queueRecv = Queue()
        self.name = name
        self.recvThread = None
        self.openStatus = False
        pass

# -----------重写函数 start----------------
    def open(self, parameter):
        pass

    def close(self):
        pass

    def send(self, packet):
        pass

    def recv(self, length):
        pass
# -----------重写函数 end----------------

    def tag(self):
        return self.name

    def isOpen(self):
        return self.openStatus

    def startRecvThread(self):
        self.recvThread = ComPortRead(self.queueRecv, self.recv, self.tag())
        self.recvThread.start()
        pass

    def stopRecv(self):
        if self.recvThread is not None:
            self.recvThread.exit()

    def isRecvThreadAlive(self):
        if self.recvThread is not None:
            return self.recvThread.isAlive()
        return False
    
    def release(self):
        self.close()
        self.openStatus = False
        self.stopRecv()


# 串口子对象
class SerialPort(ComInterface):
    def __init__(self, name) -> None:
        super().__init__(name)
        self.port = serial.Serial()

    def open(self, parameter):
        self.port.port = parameter["port"]
        self.port.baudrate = parameter["baudrate"]
        self.port.parity = parameter["parity"]
        self.port.stopbits = parameter["stopbits"]
        self.port.timeout = 0

        try:
            self.port.open()
        except serial.serialutil.SerialException as e:
            return False,  e.__str__()
        
        self.openStatus = True
        return True, ""

    def send(self, packet):
        try:
            self.port.write(packet)
        except serial.serialutil.SerialException as e:
            return False,  e.__str__()
        
        return True, ""

    def recv(self, length):
        return self.port.read(length)
    
    def close(self):
        self.port.close()

# TCP端口 子对象
class TcpClient(ComInterface):

    def __init__(self, name) -> None:
        super().__init__(name)
        socket.setdefaulttimeout(3)
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        

    def open(self, parameter):
        server = (parameter["host"], int(parameter["port"]))
        try:
            self.socket.connect(server)
        except Exception as e:
            return False,  e.__str__()
        
        self.openStatus = True
        return True, ""
        

    def send(self, packet):
        return self.socket.send(packet)

    def recv(self, length):
        return self.socket.recv(length)

    def close(self):
        self.socket.close()

    
